package com.katesoft.scale4j.web.model;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.envers.Audited;
import org.springframework.core.Constants;
import org.springframework.security.core.GrantedAuthority;

import com.katesoft.scale4j.persistent.model.unified.AbstractPersistentEntity;
import com.katesoft.scale4j.web.security.ISecurityRoles;

/**
 * Classical implementation of Role entity.
 * 
 * @author kate2007
 */
@Entity
@Audited
@Table(name = "t_role")
@org.hibernate.annotations.Entity(dynamicUpdate = true)
@Access(AccessType.FIELD)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@NamedQueries(value = { @NamedQuery(
                                    name = Role.QUERY_FIND_BY_ROLE,
                                    query = "select r from Role r where r." + Role.PROP_ROLE
                                             + " = :username") })
public class Role extends AbstractPersistentEntity implements ISecurityRoles, GrantedAuthority {
   private static final long serialVersionUID = 6512609849946320517L;
   // queries
   public static final String QUERY_FIND_BY_ROLE = "role.find_by_role";
   // properties
   public static final String PROP_ROLE = "role";
   public static final String PROP_DESCRIPTION = "description";
   // ***********************************************************************
   // ************************ persistent fields ****************************
   // ***********************************************************************
   @Column(name = "role", nullable = false, length = 100)
   private String role;
   @Column(name = "description", length = 2000)
   private String description;

   // ***********************************************************************
   // ************************* (getters+setters) ***************************
   // ***********************************************************************

   public Role() {
      super();
   }

   public Role(String role) {
      this.role = role;
   }

   public String getRole() {
      return role;
   }

   public void setRole(final String role) {
      this.role = role;
   }

   public String getDescription() {
      return description;
   }

   public void setDescription(final String description) {
      this.description = description;
   }

   @Transient
   @Override
   /**
    * spring security authority field.
    */
   public String getAuthority() {
      return getRole();
   }

   public static Collection<String> supportedRoles() {
      Collection<String> roles = new HashSet<String>();
      Constants constants = new Constants(ISecurityRoles.class);
      Set<Object> values = constants.getValues("ROLE");
      for (Object object : values) {
         if (object instanceof String) {
            roles.add((String) object);
         }
      }
      return roles;
   }
}
